package com.best.service;

import com.best.dao.SaveDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * @author Jiang Akang
 * employeeId: BG435424
 * @date 2021/2/2
 **/
@Service
public class SaveService {

    @Autowired
    private SaveDao saveDao;

    @Autowired
    private SaveService saveService;

    @Autowired
    private DeadLockHelper deadLockHelper;

    /**
     * 死锁异常
     */
    public void deadLock() {
        deadLockHelper.deadLock();
    }
    /**
     * 普通异常
     */
    public Integer arithmeticException() {
        int value = 1 / 0;
        return value;
    }

    /**
     *  保存人名数据
     * @param name
     */
    public void savePerson(String name) {
        saveDao.insert(name);
    }

    /**
     * 第一种情况: 外层方法，内层方法都没事务，外层方法抛出异常；
     * 结果: 外层方法插入成功，报错以后，内层方法不执行，未插入成功；
     */
//    public void outerTransaction() {
//        savePerson("outer");
//        arithmeticException();
//        innerTransaction();
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//    }

//    /**
//     * 第二种情况: 外层方法，加事务，内层方法未加事务注解，外层方法抛出异常；
//     * 结果: 外层方法回滚，报错以后，内层方法不执行，内外层都未插入成功；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        arithmeticException();
//        innerTransaction();
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//    }

//    /**
//     * 第三种情况: 外层方法，内层方法都未加Transaction，内层方法抛异常；
//     * 结果: outer和inner都插入成功；
//     */
//    public void outerTransaction() {
//        savePerson("outer");
//        innerTransaction();
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//    }

//    /**
//     * 第四种情况: 外层方法加Transaction，内层方法未加注解，内层方法抛异常；
//     * 结果: outer和inner都未插入成功，事务回滚；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        innerTransaction();
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//    }

//    /**
//     * 第五种情况: 外层方法加Transaction，内层方法未加注解，内层方法抛异常, 外层方法对内层方法try catch；
//     * 结果: 事务失效，outer和inner都插入成功；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            innerTransaction();
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException();
//        }
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//    }

//    /**
//     * 第六种情况: 外层方法加Transaction，内层方法未加注解，内层方法抛异常, 外层方法对内层方法try catch，但是把异常抛了出来；
//     * 结果: 事务回滚，outer和inner都未插入成功；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            innerTransaction();
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException();
//        }
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//    }

//    /**
//     * 第七种情况: 外层方法加Transaction，内层方法未加注解，内层方法抛异常, 外层方法对内层方法try catch, 但是手动开启rollBack；
//     * 结果: 事务回滚，outer和inner都未插入成功；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            innerTransaction();
//        } catch (Exception e) {
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//        }
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//    }

//    /**
//     * 第八种情况: 外层方法加Transaction，内层方法未加注解，内层方法抛异常, 外层方法对内层方法try catch，并对内层方法自己注入自己；
//     * 结果: 事务未回滚，outer和inner插入成功，inner1报错之后，未插入成功；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            saveService.innerTransaction();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//        savePerson("inner1");
//    }

//    /**
//     * 第九种情况: 内外层方法加Transaction，内层方法抛异常, 外层方法对内层方法try catch，并对内层方法自己注入自己；
//     * 结果: 事务回滚，inner，inner1，outer都未插入成功；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            saveService.innerTransaction();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    @Transactional
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//        savePerson("inner1");
//    }

//    /**
//     * 第十种情况: 内外层方法加Transaction，外层方法对内层方法try catch，并对内层方法自己注入自己，try里抛出异常；
//     * 结果: 事务未回滚，异常被catch事务失效；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            saveService.innerTransaction();
//            arithmeticException();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    @Transactional
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//        savePerson("inner1");
//    }

    /**
     * 第十一种情况: 内外层方法加Transaction，内层也抛异常，外层方法对内层方法try catch，并对内层方法自己注入自己，try里抛出异常；
     * 结果: 事务回滚，被重新标记为rollback；
     */
    @Transactional
    public void outerTransaction() {
        savePerson("outer");
        try {
            saveService.innerTransaction();
            arithmeticException();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Transactional
    public void innerTransaction() {
        savePerson("inner");
        arithmeticException();
        savePerson("inner1");
    }

//    /**
//     * 第十二种情况: 外层方法加Transaction，内层方法加requere_new, 内层也抛异常，外层方法对内层方法try catch，并对内层方法自己注入自己，try里抛出异常；
//     * 结果: 内层事务回滚，外层事务失效；
//     */
//    @Transactional
//    public void outerTransaction() {
//        savePerson("outer");
//        try {
//            saveService.innerTransaction();
//            arithmeticException();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    @Transactional(propagation = Propagation.REQUIRES_NEW)
//    public void innerTransaction() {
//        savePerson("inner");
//        arithmeticException();
//        savePerson("inner1");
//    }



}
